package com.ruoyi.controller;

import com.ruoyi.domain.common.ResponseResult;
import com.ruoyi.domain.common.UserHolder;
import com.ruoyi.domain.entity.User;
import com.ruoyi.exception.BaseException;
import com.ruoyi.service.UserService;
import com.ruoyi.utils.EmailUtil;
import com.ruoyi.utils.JJWTUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@RestController()
@RequestMapping("/user")
@Tag(name = "用户模块接口")
@Slf4j
public class UserController extends ResultBaseController<UserService, User>{
    @Autowired
    UserService userService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private EmailUtil emailUtil;

    @PostMapping("/login")
    @Operation(summary = "密码登录")
    public ResponseResult<String> Login(@RequestParam String phone, @RequestParam String password, @RequestParam String captcha){
        log.info("发起登录请求");
        User user = userService.getUserByPhone(phone);
        // 从 Redis 获取验证码（假设存储的验证码键为 "captcha:{验证码}"）
        captcha=captcha.toLowerCase();
        String storedCaptcha = redisTemplate.opsForValue().get("captcha:" + captcha);
        if(user == null){
            return ResponseResult.error("用户不存在");
        }
        if(!BCrypt.checkpw(password, user.getPassword())){
            return ResponseResult.error("密码错误");
        }
        // 校验验证码是否正确
        if (storedCaptcha == null || !storedCaptcha.equalsIgnoreCase(captcha)) {
            return ResponseResult.error("验证码错误");
        }
        if(!user.getStatus()){
            return ResponseResult.error("用户已注销");
        }
        String token = JJWTUtils.createToken(user.getId());
        return ResponseResult.success(token,"登录成功");
    }

    // 短信登录
    @GetMapping("/smsLogin")
    @Operation(summary = "短信登录")
    public ResponseResult<String> smsLogin(String phone,String captcha) {
        log.info("发起短信登录请求");
        // 从 Redis 获取验证码
        String storedCaptcha = redisTemplate.opsForValue().get("sms:captcha:" + phone);

        // 校验验证码是否正确
        if (storedCaptcha == null || !storedCaptcha.equalsIgnoreCase(captcha)) {
            return ResponseResult.error("验证码错误");
        }

        User user = userService.getUserByPhone(phone);
        if (user == null) {
            return ResponseResult.error("用户不存在");
        }
        if (!user.getStatus()) {
            return ResponseResult.error("用户已注销");
        }

        String token = JJWTUtils.createToken(user.getId());
        return ResponseResult.success(token, "登录成功");
    }

    @GetMapping("/getInfo")
    @Operation(summary = "获取用户信息")
    public ResponseResult<User> getInfo(){
        log.info("发起登录请求，会被拦截");
        return ResponseResult.success(userService.getById(UserHolder.getUserId()));
    }

    @PostMapping("/register")
    public ResponseResult<String> register(@RequestBody User user,@RequestParam String captcha){
        if(userService.getUserByPhone(user.getPhone())!=null){
            return ResponseResult.error("用户已存在，是否忘记密码");
        }
        // 从 Redis 获取验证码saz
        String storedCaptcha = redisTemplate.opsForValue().get("sms:captcha:" + user.getPhone());

        // 校验验证码是否正确
        if (storedCaptcha == null || !storedCaptcha.equalsIgnoreCase(captcha)) {
            return ResponseResult.error("验证码错误");
        }
        //密码加密
        String salt = BCrypt.gensalt();
        String pwd = BCrypt.hashpw(user.getPassword(), salt);
        user.setPassword(pwd);
        Random random = new Random();
        // 获取当前时间戳
        long timestamp = System.currentTimeMillis();
        // 生成一个 4 位随机数
        int randomNum = random.nextInt(10000);

        // 将时间戳和随机数拼接，生成一个账号
        String randomAccount = String.format("user%08d%04d", timestamp, randomNum);
        user.setUserName(randomAccount);
        try {
            userService.save(user);
        }catch (Exception e){
            throw new BaseException("注册失败");
        }
        return ResponseResult.success("注册成功");
    }

    @GetMapping("/updatePassword")
    public ResponseResult<String> updatePassword(@RequestParam String phone, @RequestParam String password){
        //密码加密
        String salt = BCrypt.gensalt();
        password = BCrypt.hashpw(password, salt);
        if(userService.updatePassword(phone,password)){
            return ResponseResult.success("修改成功");
        }
        return ResponseResult.error("修改失败");
    }

    @GetMapping("/checkPassword")
    public boolean checkPassword(String phone,String password) {
        return userService.checkPassword(phone, password);
    }

    @PostMapping("/updateUserInfo")
    public ResponseResult<String> updateUserInfo(@RequestBody User user){
        if(userService.updateUserInfo(user)){
            return ResponseResult.success("修改成功");
        }
        return ResponseResult.error("修改失败");
    }

    // 生成邮箱验证码
    private String generateVerificationCode() {
        Random random = new Random();
        int code = 100000 + random.nextInt(900000); // 生成6位数字验证码
        return String.valueOf(code);
    }

    // 发送邮箱验证码
    @GetMapping("/sendEmailVerification")
    @Operation(summary = "发送邮箱验证码")
    public ResponseResult<String> sendVerificationCode(@RequestParam String email) {
        String verificationCode = generateVerificationCode();
        String subject = "验证码";
        String message = "您的验证码是: " + verificationCode + "，请在5分钟内使用。";

        try {
            emailUtil.sendEmail(email, subject, message);
            // 将验证码存储到Redis中，设置过期时间为5分钟
            redisTemplate.opsForValue().set("email:captcha:" + email, verificationCode, 5, TimeUnit.MINUTES);
            return ResponseResult.success("验证码已发送");
        } catch (Exception e) {
            log.error("发送验证码失败", e);
            return ResponseResult.error("请输入正确邮箱！");
        }
    }

    // 验证邮箱
    @GetMapping("/verifyEmail")
    @Operation(summary = "验证邮箱")
    public ResponseResult<String> verifyEmail(@RequestParam String email, @RequestParam String captcha) {
        // 从 Redis 获取验证码
        String storedCaptcha = redisTemplate.opsForValue().get("email:captcha:" + email);

        // 校验验证码是否正确
        if (storedCaptcha == null || !storedCaptcha.equalsIgnoreCase(captcha)) {
            return ResponseResult.error("验证码错误");
        }

        // 更新用户邮箱
        User user = userService.getUserByEmail(email);
        if (user != null) {
            return ResponseResult.error("邮箱已被注册");
        }

        User currentUser = userService.getById(UserHolder.getUserId());
        if (currentUser == null) {
            return ResponseResult.error("用户不存在");
        }
        currentUser.setEmail(email);
        try {
            userService.updateUserInfo(currentUser);
        } catch (Exception e) {
            throw new BaseException("更新邮箱失败");
        }

        return ResponseResult.success("邮箱绑定成功");
    }

    // 修改手机号
    @GetMapping("/changePhone")
    @Operation(summary = "修改手机号")
    public ResponseResult<String> changePhone(@RequestParam String oldPhone,@RequestParam String newPhone, @RequestParam String captcha) {
        // 检查新手机号是否已注册
        if (userService.getUserByPhone(newPhone)!=null) {
            return ResponseResult.error("手机号已注册");
        }

        // 从 Redis 获取验证码
        String storedCaptcha = redisTemplate.opsForValue().get("sms:captcha:" + newPhone);

        // 校验验证码是否正确
        if (storedCaptcha == null || !storedCaptcha.equalsIgnoreCase(captcha)) {
            return ResponseResult.error("验证码错误");
        }

        // 更新用户手机号
        try {
            userService.updatePhoneByOldPhone(oldPhone, newPhone);
        } catch (Exception e) {
            log.error("更新手机号失败", e);
            return ResponseResult.error("更新手机号失败");
        }

        return ResponseResult.success("手机号修改成功");
    }

    @PostMapping("/logout")
    public ResponseResult<String> logoutUser(@RequestParam String phone) {
        try {
            userService.logoutUser(phone);
        }catch (Exception e){
            return ResponseResult.error("注销失败");
        }
        return ResponseResult.success("注销成功");
    }
    //找回密码
    @PostMapping("/resetPassword")
    public ResponseResult<String> resetPassword(@RequestParam String phone, @RequestParam String password, @RequestParam String captcha){
        if(userService.getUserByPhone(phone)==null){
            return ResponseResult.error("手机号未注册");
        }
        // 从 Redis 获取验证码saz
        String storedCaptcha = redisTemplate.opsForValue().get("sms:captcha:" + phone);
        // 校验验证码是否正确
        if (storedCaptcha == null || !storedCaptcha.equalsIgnoreCase(captcha)) {
            return ResponseResult.error("验证码错误");
        }
        return updatePassword(phone,password);
    }
}